home *** CD-ROM | disk | FTP | other *** search
- /* ------------- popdown.c ----------- */
-
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include "dflat.h"
-
- static int SelectionWidth(struct PopDown *);
-
- extern char *Clipboard;
- static MENU *mnu;
-
- int PopDownProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
- {
- int wd, rtn, i;
- struct PopDown *pd1;
- char sep[80], *cp = sep;
- char sel[80];
- static struct PopDown *ActivePopDown = NULL;
-
- switch (msg) {
- case CREATE_WINDOW:
- ClearAttribute(wnd, TITLEBAR |
- VSCROLLBAR |
- MOVEABLE |
- SIZEABLE |
- HSCROLLBAR);
- rtn = BaseWndProc(POPDOWNMENU, wnd, msg, p1, FALSE);
- SendMessage(wnd, CAPTURE_MOUSE, 0, 0);
- SendMessage(wnd, CAPTURE_KEYBOARD, 0, 0);
- SendMessage(NULLWND, SAVE_CURSOR, 0, 0);
- SendMessage(NULLWND, HIDE_CURSOR, 0, 0);
- return rtn;
- case SETFOCUS:
- return FALSE;
- case BUILD_SELECTIONS:
- mnu = (void *) p1;
- ActivePopDown = pd1 = mnu->Selections;
- wd = MenuWidth(ActivePopDown)-2;
- while (wd--)
- *cp++ = LINE;
- *cp = '\0';
- while (pd1->SelectionTitle != NULL) {
- if (*pd1->SelectionTitle == LINE)
- SendMessage(wnd, ADDTEXT, (PARAM) sep, 0);
- else {
- memset(sel, '\0', sizeof sel);
- if (pd1->Attrib & INACTIVE) {
- strcpy(sel, " ");
- *sel = CHANGECOLOR;
- *(sel+1) = cfg.clr.InactiveSelFG | 0x80;
- *(sel+2) = cfg.clr.PopDownBG | 0x80;
- }
- strcat(sel, " ");
- CopyCommand(sel+strlen(sel), pd1->SelectionTitle,
- pd1->Attrib & INACTIVE, cfg.clr.PopDownBG);
- if (pd1->Attrib & CHECKED)
- *sel = CHECKMARK;
- if (pd1->Accelerator) {
- int i;
- int wd1 = 2+SelectionWidth(ActivePopDown) - strlen(pd1->SelectionTitle);
- for (i = 0; keys[i].keylabel; i++)
- if (keys[i].keycode == pd1->Accelerator) {
- while (wd1--)
- strcat(sel, " ");
- strcat(sel, "[");
- strcat(sel, keys[i].keylabel);
- strcat(sel, "]");
- break;
- }
- }
- strcat(sel, " ");
- sel[strlen(sel)-1] = RESETCOLOR;
- SendMessage(wnd, ADDTEXT, (PARAM) sel, 0);
- }
- pd1++;
- PostMessage(wnd, LB_SETSELECTION, mnu->Selection, 0);
- }
- break;
- case HORIZSCROLL:
- return FALSE;
- case LEFT_BUTTON:
- if (SendMessage(wnd, INSIDE_WINDOW, p1, p2))
- break;
- /* --- note: fall through here --- */
- case DOUBLE_CLICK:
- if (p2 == GetTop(GetParent(wnd)))
- PostMessage(GetParent(wnd), msg, p1, p2);
- SendMessage(wnd, CLOSE_WINDOW, 0, 0);
- return FALSE;
- case BORDER:
- rtn = BaseWndProc(POPDOWNMENU, wnd, msg, p1, FALSE);
-
- for (i = 0; i < ClientHeight(wnd); i++) {
- if (*TextLine(wnd, i) == LINE) {
- wputch(wnd, LEDGE, -1, i);
- wputch(wnd, REDGE, WindowWidth(wnd)-2, i);
- }
- }
- return rtn;
-
- case LB_SELECTION:
- rtn = BaseWndProc(POPDOWNMENU, wnd, msg, p1, FALSE);
- if (ActivePopDown != NULL) {
- mnu->Selection = (int)p1;
- if (p2 && GetParent(wnd)) {
- int *attr = &(ActivePopDown+(int)p1)->Attrib;
- if (*attr & INACTIVE)
- beep();
- else if (*attr & TOGGLE) {
- char *tl = TextLine(wnd, (int)p1);
- *attr ^= CHECKED;
- if (*attr & CHECKED)
- *tl = CHECKMARK;
- else
- *tl = ' ';
- SendMessage(wnd, PAINT, 0, 0);
- }
- else {
- PostMessage(GetParent(wnd), COMMAND,
- (ActivePopDown+(int)p1)->ActionId, p1);
- SendMessage(wnd, CLOSE_WINDOW, 0, 0);
- }
- }
- }
- return rtn;
- case KEYBOARD:
- if (ActivePopDown != NULL) {
- int c = tolower((int)p1);
- int sel = 0;
- struct PopDown *pd = ActivePopDown;
- while (pd->SelectionTitle != NULL) {
- char *cp = strchr(pd->SelectionTitle,
- SHORTCUTCHAR);
- if (cp && tolower(*(cp+1)) == c ||
- pd->Accelerator == (int) p1) {
- PostMessage(wnd, LB_SELECTION, sel, TRUE);
- return TRUE;
- }
- pd++, sel++;
- }
- }
- if (p1 == ESC) {
- SendMessage(wnd, CLOSE_WINDOW, 0, 0);
- return TRUE;
- }
- switch ((int)p1) {
- case FWD:
- case BS:
- if (GetClass(GetParent(wnd)) == MENUBAR) {
- PostMessage(GetParent(wnd), KEYBOARD, p1, p2);
- return TRUE;
- }
- break;
- case UP:
- if (wnd->selection == 0) {
- if (wnd->wlines == ClientHeight(wnd)) {
- PostMessage(wnd, LB_SELECTION, wnd->wlines-1, FALSE);
- return TRUE;
- }
- }
- return BaseWndProc(POPDOWNMENU, wnd, msg, p1, p2);
- case DN:
- if (wnd->selection == wnd->wlines-1) {
- if (wnd->wlines == ClientHeight(wnd)) {
- PostMessage(wnd, LB_SELECTION, 0, FALSE);
- return TRUE;
- }
- }
- return BaseWndProc(POPDOWNMENU, wnd, msg, p1, p2);
- case HOME:
- case END:
- case '\r':
- return BaseWndProc(POPDOWNMENU, wnd, msg, p1, p2);
- }
- return FALSE;
- case CLOSE_WINDOW:
- SendMessage(wnd, RELEASE_MOUSE, 0, 0);
- SendMessage(wnd, RELEASE_KEYBOARD, 0, 0);
- SendMessage(GetParent(wnd), CLOSE_POPDOWN, 0, 0);
- ActivePopDown = NULL;
- mnu = NULL;
- SendMessage(NULLWND, RESTORE_CURSOR, 0, 0);
- break;
- default:
- break;
- }
- return BaseWndProc(POPDOWNMENU, wnd, msg, p1, p2);
- }
-
- int MenuHeight(struct PopDown *pd)
- {
- int ht = 0;
- while (pd[ht].SelectionTitle != NULL)
- ht++;
- return ht+2;
- }
-
- int MenuWidth(struct PopDown *pd)
- {
- int wd = 0, i;
- int len = 0;
-
- wd = SelectionWidth(pd);
- while (pd->SelectionTitle != NULL) {
- if (pd->Accelerator) {
- for (i = 0; keys[i].keylabel; i++)
- if (keys[i].keycode == pd->Accelerator) {
- len = max(len, 2+strlen(keys[i].keylabel));
- break;
- }
- }
- pd++;
- }
- return wd+5+len;
- }
-
- static int SelectionWidth(struct PopDown *pd)
- {
- int wd = 0;
- while (pd->SelectionTitle != NULL) {
- int len = strlen(pd->SelectionTitle)-1;
- wd = max(wd, len);
- pd++;
- }
- return wd;
- }
-
- int CopyCommand(char *dest, char *src, int skipcolor, int bg)
- {
- char *d = dest;
- while (*src && *src != '\n') {
- if (*src == SHORTCUTCHAR) {
- src++;
- if (!skipcolor) {
- *dest++ = CHANGECOLOR;
- *dest++ = cfg.clr.ShortCutFG | 0x80;
- *dest++ = bg | 0x80;
- *dest++ = *src++;
- *dest++ = RESETCOLOR;
- }
- }
- else
- *dest++ = *src++;
- }
- return (int) (dest - d);
- }
-